<?php
/**
 * @notes:
 * @return
 * @author: admin
 * @date: 2024/9/7
 */


namespace addons\shopro\service\lucky;


use addons\shopro\service\commission\Agent as AgentService;
use addons\shopro\service\order\OrderCreate;
use addons\shopro\service\user\User as UserService;
use addons\shopro\service\Wallet as WalletService;
use app\admin\model\shopro\commission\Agent;
use app\admin\model\shopro\lucky\Auto;
use app\admin\model\shopro\lucky\Order;
use app\admin\model\shopro\lucky\Server;
use app\admin\model\shopro\lucky\User;
use app\admin\model\shopro\tokens\Config;
use app\admin\model\shopro\tokens\Record;
use app\admin\model\shopro\tokens\Trade;
use app\admin\model\shopro\user\Address;
use app\admin\model\shopro\Withdraw;
use think\Db;
use think\Exception;
use app\admin\model\shopro\goods\SkuPrice;
use app\admin\model\shopro\user\WalletLog;

class LuckyService
{
    protected $query = null;
    protected $format = null;

    public function __construct(\Closure $format = null, \think\db\Query $query = null)
    {
        $this->query = $query ?: new Server();
        $this->relationSearch = true;
        $this->format = $format;
    }

    /***
     * @notes:
     * 获取预约中的活动
     * @return false|\PDOStatement|string|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/8 0:06
     */
    public function getList($user)
    {

        $data=$this->query->with('goods')->where(['server.status'=>'0'])->paginate(request()->param('list_rows', 10));

        foreach ($data as $row) {
            $row->visible(['id','name','price','number','alr_number','start_time','end_time','open_lucky_time','status']);
            $row->visible(['goods']);
            $row->getRelation('goods')->visible(['title','image']);
        }
        $list=[
            'data'=>$data,
            'money'=>$user->money
        ];

        return $list;
    }


    /***
     * @notes:预购处理
     * @param $prams
     * @param $user
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/10 0:03
     */
    public function auotSetLucky($prams,$user)
    {
        Db::startTrans();
        try{
            if($prams['number']<=0){
                throw new Exception('数量不正确！');
            }
            if(!$user){
                throw new Exception('用户不存在！');
            }
            $address=Address::where(['user_id'=>$user['id'],'is_default'=>1])->find();
            if(empty($address)){
                throw new Exception('请先填写收货地址，并设置为默认！');
            }
            $server =$this->query->where('id',$prams['server_id'])->find();
            if(!$server){
                throw new Exception('活动不存在！');
            }
            $time = date('Y-m-d H:i:s');
            if($time < $server['start_time'])  throw new Exception('未到预购时间');
            if($time > $server['end_time'])  throw new Exception('预购时间已结束');

            $time=time();
            $user=\app\admin\model\shopro\user\User::where(['id'=>$user->id])->lock(true)->find();
            $money=bcmul($server['price'],$prams['number'],2);
            if($money>$user->money){
                throw new Exception('消费券消费券不足！');
            }
            $agent=null;
            if(WalletService::changeNoEx($user,'money',-$money,'lucky_pay')){
                $luck_user = User::where(['user_id'=>$user->id,'lucky_id'=>$prams['server_id']])->find();
                if($luck_user){
                    $luck_user_id=$luck_user['id'];
                    $luck_user->number = ['inc',$prams['number']];
                    $luck_user->total_price=['inc',$money] ;
                    $luck_user->goods_id=$server['goods_id'];
                    $luck_user->updatetime=$time;
                    $luck_user->save();
                }else{
                    $data=['user_id'=>$user->id,'lucky_id'=>$prams['server_id'],'goods_id'=>$server['goods_id'],'number'=>$prams['number'],'total_price'=>$money,'createtime'=>$time,'updatetime'=>$time];
                    $luck_user_id=(new User())->insertGetId($data);
                    $data['id']=$luck_user_id;
                    $luck_user=$data;

                }
                $luck_order_data=[];
                for($i=0;$i<$prams['number'];$i++){
                    array_push($luck_order_data,['user_id'=>$user->id,'lucky_id'=>$prams['server_id'],'goods_id'=>$server['goods_id'],'lucky_user_id'=>$luck_user_id,'order_num'=>get_sn($user->id),'price'=>$server['price']]);
                }
                (new Order())->saveAll($luck_order_data);
                $server->setInc('alr_number',$prams['number']);
                $agent = new AgentService($user);
                $orderAgent = new \addons\shopro\service\commission\Agent($user->parent_user_id);
                if($orderAgent->isAgentAvaliable()){
                    $orderAgent->agent->setInc('today_driect_money', $money);
                }

            }else{
                throw new Exception('预购失败！');
            }
            Db::commit();
            // 分销商数据统计&升级(异步执行)
            if($agent){
                $agent->createAsyncAgentUpgrade();
            }
            return true;
        }catch (\Exception $e){
            Db::rollback();
            //print($e->getMessage());
            error_stop($e->getMessage());
        }
        return false;
    }


    /***
     * @notes:预购处理
     * @param $prams
     * @param $user
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author: 小谢
     * @date: 2024/9/10 0:03
     */
   public function setLucky($prams,$user)
    {

            if($prams['number']<=0){
                error_stop('数量不正确！');
            }
            if(!$user){
                error_stop('用户不存在！');
            }
            $address=Address::where(['user_id'=>$user['id'],'is_default'=>1])->find();
            if(empty($address)){
                error_stop('请先填写收货地址，并设置为默认！');
            }
            $server =$this->query->where('id',$prams['server_id'])->find();
            if(!$server){
                error_stop('活动不存在！');
            }
            $time = date('Y-m-d H:i:s');
            if($time < $server['start_time'])  throw new Exception('未到预购时间');
            if($time > $server['end_time'])  throw new Exception('预购时间已结束');

                if ($user->rep_password != md5(md5($prams['rep_password']) . $user->salt)) {
                    error_stop('支付密码错误！');
                }

            $time=time();
            $user=\app\admin\model\shopro\user\User::where(['id'=>$user->id])->lock(true)->find();
            $money=bcmul($server['price'],$prams['number'],2);
            if($money>$user->money){
                error_stop('消费券不足！');
            }
        Db::startTrans();
        try{
            $agent=null;
            if(WalletService::changeNoEx($user,'money',-$money,'lucky_pay')){
               $luck_user = User::where(['user_id'=>$user->id,'lucky_id'=>$prams['server_id']])->find();
               if($luck_user){
                   $luck_user_id=$luck_user['id'];
                   $luck_user->number = ['inc',$prams['number']];
                   $luck_user->total_price=['inc',$money] ;
                   $luck_user->goods_id=$server['goods_id'];
                   $luck_user->updatetime=$time;
                   $luck_user->save();
               }else{
                   $data=['user_id'=>$user->id,'lucky_id'=>$prams['server_id'],'goods_id'=>$server['goods_id'],'number'=>$prams['number'],'total_price'=>$money,'createtime'=>$time,'updatetime'=>$time];
                   $luck_user_id=(new User())->insertGetId($data);
                   $data['id']=$luck_user_id;
                   $luck_user=$data;

               }
               $luck_order_data=[];
               for($i=0;$i<$prams['number'];$i++){
                   array_push($luck_order_data,['user_id'=>$user->id,'lucky_id'=>$prams['server_id'],'goods_id'=>$server['goods_id'],'lucky_user_id'=>$luck_user_id,'order_num'=>get_sn($user->id),'price'=>$server['price']]);
               }
               (new Order())->saveAll($luck_order_data);
                $server->setInc('alr_number',$prams['number']);
                $agent = new AgentService($user);
                $orderAgent = new \addons\shopro\service\commission\Agent($user->parent_user_id);
                if($orderAgent->isAgentAvaliable()){
                    $orderAgent->agent->setInc('today_driect_money', $money);
                }

            }else{
                Db::rollback();
                error_stop('预购失败！');
            }
            Db::commit();
            // 分销商数据统计&升级(异步执行)
            if($agent){
                $agent->createAsyncAgentUpgrade();
            }
            return true;
        }catch (\Exception $e){
            Db::rollback();
            error_stop($e->getMessage());
        }
    }




    /***
     * 执行预购抽签任务
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function openLucky()
    {
        $time = date('Y-m-d H:i:s');
        $server=Server::where(['status'=>'0'])->where('open_lucky_time','<=',$time)->select();
        if(!empty($server)){
            foreach ($server as &$item){
                //$userLucky=User::where(['lucky_id'=>$item['id'],'stutas'=>'0'])->find();
                $lucky_number= ceil($item['alr_number']*$item['lucky_rate']*0.01);
                //先处理必中的
                Order::where(['lucky_id'=>$item['id'],'status'=>'0','is_lucky'=>1])
                    ->chunk(20,function ($v) use ($item,&$lucky_number){
                        $data=[
                            'item' =>$item,
                            'type'=>1,
                            'list'=>$v
                        ];
                        \think\Queue::push('\addons\shopro\job\Luckey@luckey', $data, 'shopro-high');
                        $lucky_number-=count($v);
                    });

                //处理不中的
                Order::where(['lucky_id'=>$item['id'],'status'=>'0','is_lucky'=>2])
                    ->chunk(20,function ($v) use ($item,&$lucky_number){
                        $data=[
                            'item' =>$item,
                            'type'=>2,
                            'list'=>$v
                        ];
                        \think\Queue::push('\addons\shopro\job\Luckey@luckey', $data, 'shopro-high');

                    });
                //处理随机中的
                if($lucky_number>0){
                   $list=Db::query(sprintf("SELECT * FROM cj_shopro_lucky_order WHERE lucky_id=%s and status='0' and is_lucky=0 ORDER BY RAND() LIMIT %d",$item['id'],$lucky_number));
                    if($list){
                        $blocks = array_chunk($list, 20);
                        foreach ($blocks as $value){
                            $data=[
                                'item' =>$item,
                                'type'=>1,
                                'list'=>$value
                            ];
                            \think\Queue::push('\addons\shopro\job\Luckey@luckey', $data, 'shopro-high');
                            $lucky_number-=count($value);
                        }
                    }

                }
                //处理剩余不中的
                Order::where(['lucky_id'=>$item['id'],'status'=>'0','is_lucky'=>0])
                    ->chunk(20,function ($v) use ($item,&$lucky_number){
                        $data=[
                            'item' =>$item,
                            'type'=>2,
                            'list'=>$v
                        ];
                        \think\Queue::push('\addons\shopro\job\Luckey@luckey', $data, 'shopro-high');
                    });
                \think\Queue::push('\addons\shopro\job\Luckey@luckyShop', ['lucky_id'=>$item['id'],'goods_id'=>$item['goods_id']], 'shopro-high');
                $item->status='1';
                $item->save();
            }
            return '执行成功';
        }
        return '没有需要执行的活动';


    }



    /***
     * 处理每日数据更新
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function updateDayData()
    {
        //先处理每日价格更新
        
        $maxPrice=Record::order('id','DESC')->limit(1)->find();
        $trade=$maxPrice['price'];
        
        Db::startTrans();
        try{

            $agent=(new \app\admin\model\shopro\commission\Agent)->select();
            if($agent){
                foreach ($agent as &$item){
                    $item->yesday_driect_money=$item->today_driect_money;
                    $item->yesday_order_money=$item->today_order_money;
                    $item->yesday_commission_mony=$item->today_commission_mony;
                    $item->yesday_team_money=$item->today_team_money;
                    $item->today_driect_money=0;
                    $item->today_order_money=0;
                    $item->today_commission_mony=0;
                    $item->today_team_money=0;
                    $item->save();
                }
            }

            $confing=Config::where(['id'=>1])->find();

            (new Record)->save([
                'price'=>$trade+$confing['up_money'],
                'createtime'=>date('Y-m-d H:i:s')
            ]);

            Config::where(['id'=>1])->update(['current_price'=>$trade,'day_tokens'=>0]);
            Db::commit();
            print('行情更新完成');
        }catch (\Exception $e){
            Db::rollback();
            print('行情更新失败');
        }
    }


    public function updateTokens()
    {
        $tokens_config=Config::where(['id'=>1])->find();
        if($tokens_config['score_rate']>0 && $tokens_config['current_price']>0){
            \app\admin\model\shopro\user\User::where('score','>',0)->where(['status'=>'normal'])
                ->chunk(50,function ($item) use ($tokens_config){
                    foreach ($item as $value){
                        /*$userWalletLog=WalletLog::where(['user_id'=>$value['id'],'type'=>'money','event'=>'lucky_pay'])->whereTime('createtime','-96 hour')->sum('amount');
                        $userWalletLog=abs($userWalletLog);
                        if($userWalletLog>0){*/
                            $score=round($value['total_score']*$tokens_config['score_rate'],3);
                            if($score>$value['score']){
                                $score=$value['score'];
                            }
                            if($score>0){
                                $tokens=bcdiv($score,$tokens_config['current_price'],3);
                                Db::startTrans();
                                try{
                                    if(WalletService::change($value,'score',-$score,'release_day')){
                                        WalletService::change($value,'tokens',$tokens,'score_release');
                                        Config::where(['id'=>1])->setInc('released',$tokens);
                                        Config::where(['id'=>1])->setInc('day_tokens',$tokens);
                                    }else{
                                        print('4654');
                                    }
                                    Db::commit();
                                    $data=['user_id'=>$value['id'],'tokens'=>$tokens];
                                    \think\Queue::push('\addons\shopro\job\Commission@tokensPlan', $data, 'shopro-high');
                                }catch (\Exception $e){
                                    Db::rollback();
                                    print($e->getMessage());
                                }

                            }
                        //}
                    }
                });
        }
        \think\Queue::push('\addons\shopro\job\Commission@tokensNode',[], 'shopro-high');
        print('每日释放处理完成！');

    }




    public function tokensPlan($userModel,$tokens,$up_tokens=0)
    {
        print ("1");
        $up_user=\app\admin\model\shopro\user\User::where(['id'=>$userModel['parent_user_id']])->find();
        if(!$up_user){
            print ("2");
            return ;
        }

        $currentAgent = Agent::with('tokens_level_info')->find($up_user->id);
        if(!$currentAgent || $currentAgent->tokens_level_info->range<=0){
            $this->tokensPlan($up_user,$tokens,$up_tokens);
        }

        $range=$currentAgent->tokens_level_info->range/100;
        $ran_tokens=bcmul($tokens,$range,6)*1;
        $ran_tokens=$ran_tokens-$up_tokens;
        print ("3");
        if($ran_tokens>0){
            print ("4");
            WalletService::change($up_user,'tokens',$ran_tokens,'score_range_release');
            $up_tokens=$up_tokens+$ran_tokens;
        }else{
            return;
        }
        $this->tokensPlan($up_user,$tokens,$up_tokens);
    }


    public function updataScore()
    {
        \app\admin\model\shopro\user\User::where('total_score','>',0)->chunk(20,function ($v){

            foreach ($v as $item){
                Agent::where(['user_id'=>$item['id']])->update(['score_total_all'=>$item['total_score']]);
            }
        });
    }





    /***
     * 处理每日释放通证
     * @return void
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    /*public function updateTokens_old()
    {
        $tokens_config=Config::where(['id'=>1])->find();

        $total_score=\app\admin\model\shopro\user\User::sum('score');
        $total_score=round($total_score*$tokens_config['score_rate'],2);
        $score_rate=round($tokens_config['day_released']/$total_score,8);

        \app\admin\model\shopro\user\User::where('score','>',0)->where(['status'=>'normal'])
            ->chunk(10,function ($item) use ($score_rate,$tokens_config){
            foreach ($item as $value){
                $score=round($value['score']*$tokens_config['score_rate'],2);
                $tokens=round($score*$score_rate,3);
                try{
                    if(WalletService::change($value['id'],'score',-$score,'release_day')){

                        WalletService::change($value['id'],'tokens',$tokens,'score_release');
                    }else{
                        print('4654');
                    }

                }catch (\Exception $e){
                    print($e->getMessage());
                }

            }
        });
        $tokens_config->setInc('released',$tokens_config['day_released']);
        print('每日释放处理完成！01');

    }*/

    public function updateUserAgent()
    {

        Withdraw::where('status',2)->chunk(20,function ($d){

            foreach ($d as $item){
                Withdraw::where('id',$item['id'])->setDec('paid_fee',$item['charge_fee']);
            }

        });


        print('ok!');

    }

    public function toOrder()
    {
        $num=8;
        $goods_sku_price=SkuPrice::where(['goods_id'=>7])->find();
        Db::table('cj_shop_lucky_num')->chunk(20,function ($i) use ($num,$goods_sku_price){
            foreach ($i as $item){

                if($item['shop_num']-$item['out_num']>=$num){
                    Db::startTrans();
                    try{
                        $address=Address::where(['user_id'=>$item['user_id'],'is_default'=>1])->find();
                        if($address){
                            $orderInfo=[
                                'address_id'=>$address['id'],
                                'goods_list'=>[
                                    ['goods_id'=>7,'goods_num'=>$num,'goods_sku_price_id'=>$goods_sku_price['id']]
                                ],
                                'order_type'=>'goods',
                                'user_id'=>$item['user_id'],
                            ];

                            $orderCreate = new OrderCreate($orderInfo);

                            $result = $orderCreate->calc('create');

                            $oredr=$orderCreate->create($result);
                            $pay_order=\app\admin\model\shopro\order\Order::where(['id'=>$oredr['id']])->find();

                            $pay_order->pay_fee = 200*$num;

                            $pay_order->remain_pay_fee = 0;

                            $pay_order->paid_time = time();
                            $pay_order->status = 'paid';

                            $pay_order->save();

                            Db::table('cj_shop_lucky_num')->where('id',$item['id'])->setInc('out_num',$num);

                        }else{
                            print('地址不正确！');
                        }
                        Db::commit();
                    }catch (\Exception $e){
                        print($e->getMessage());
                        Db::rollback();
                    }
                }
            }
        });
    }


    public function autoOpen($switch)
    {

        $data=[
            'withdrawal'=>$switch,
            'transaction'=>$switch,
            'release'=>$switch,
            //'order'=>$switch,
            //'bonus'=>$switch,
        ];

        \app\admin\model\shopro\Config::setConfigs('shop.basic',$data);


    }


}